﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ITAP.ShprossesBuilder.Modelling.Components.Constraints
{
    [Serializable]
    public class RemoveCorruptedShprossChain : IConstraint
    {

        #region IConstraint Members

        public bool Check(IComponent component)
        {
            return false;
        }

        public void Fix(IComponent component)
        {
            List<IComponent> chainsToRemove = new List<IComponent>();
            foreach (IComponent innerComponent in component.InnerComponents)
            {
                if (!(innerComponent is ShprossChain))
                    continue;             

                if (!this.CheckChain(innerComponent as ShprossChain))
                    chainsToRemove.Add(innerComponent);
            }

            foreach (IComponent chainToRemove in chainsToRemove)
                component.RemoveInnerComponent(chainToRemove);
        }

        private bool CheckChain(ShprossChain shprossChain)
        {
            if (shprossChain.ConnectedComponents.Count == 0)
                return false;
            int counter = 0;
            ShprossEndToEndConnector prevEndToEnd = null;
            foreach (Shpross shpross in shprossChain.ConnectedComponents)
            {
                if (prevEndToEnd == null)
                {
                    if (shpross.StartConnectedComponent is ShprossEndToEndConnector)
                    {
                        prevEndToEnd = shpross.StartConnectedComponent as ShprossEndToEndConnector;
                        counter++;
                    }
                    else if (shpross.EndConnectedComponent is ShprossEndToEndConnector)
                    {
                        prevEndToEnd = shpross.EndConnectedComponent as ShprossEndToEndConnector;
                        counter++;
                    }

                    continue;
                }

                if (shpross.StartConnectedComponent is ShprossEndToEndConnector && shpross.StartConnectedComponent.IsConnected(prevEndToEnd))
                {
                    prevEndToEnd = shpross.EndConnectedComponent as ShprossEndToEndConnector;
                    counter++;
                }
                else if (shpross.EndConnectedComponent is ShprossEndToEndConnector && shpross.EndConnectedComponent.IsConnected(prevEndToEnd))
                {
                    prevEndToEnd = shpross.StartConnectedComponent as ShprossEndToEndConnector;
                    counter++;
                }
                else
                    return false;

            }
            if (counter != shprossChain.ConnectedComponents.Count)
                return false;
            else
                return true;

        }

        private bool enabled = true;
        public bool Enabled
        {
            get
            {
                return enabled;
            }
            set
            {
                enabled = value;
            }
        }

        public ConstraintAction Action
        {
            get { return ConstraintAction.Fix; }
        }

        #endregion

        #region ICloneable Members

        public object Clone()
        {
            RemoveCorruptedShprossChain clone = new RemoveCorruptedShprossChain();
            clone.Enabled = this.enabled;
            return clone;
        }

        #endregion
    }
}
